﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SystemControllers;
using eTMS.Controllers;
using eTMS.Commons;
using SystemControllers.UsersService;

namespace eTMS.Forms.Systems
{
    public partial class FrmUsers : eTMS.Controls.BaseForm
    {
        public FrmUsers()
        {
            InitializeComponent();
        }
        #region Variables
        private UsersController controller = new UsersController();
        #endregion
        #region Screen Functions
        //Load All lable text
        private void LoadLanguage()
        {
            this.Text = UsersStringMapping.Users;
            this.labelFormTitle.Text = Constants.APP_ADMINISTRATION + " " + UsersStringMapping.Users;
            this.groupBoxDetail.Text = Constants.APP_DETAIL;
            this.groupBoxList.Text = Constants.APP_LIST;
            this.ColumnSTT.HeaderText = Constants.APP_INDEX;
            labelUserName.Text = UsersStringMapping.UserName;
            ColumnUserName.HeaderText = UsersStringMapping.UserName;
            labelPassword.Text = UsersStringMapping.Password;
            labelDisplayName.Text = UsersStringMapping.DisplayName;
            ColumnDisplayName.HeaderText = UsersStringMapping.DisplayName;
            labelEmail.Text = UsersStringMapping.Email;
            ColumnEmail.HeaderText = UsersStringMapping.Email;
            labelPhone.Text = UsersStringMapping.Phone;
            ColumnPhone.HeaderText = UsersStringMapping.Phone;
            labelActived.Text = UsersStringMapping.Actived;
            ColumnActived.HeaderText = UsersStringMapping.Actived;
            labelRole.Text = RolesStringMapping.Roles;
            Column2.HeaderText = RolesStringMapping.RoleName;
            //Search
            this.groupBoxFilter.Text = Constants.APP_SEARCH;
            cbkUserNameFilterExact.Text = Constants.APP_SEARCH_EXACT;
            labelUserNameFilter.Text = UsersStringMapping.UserName;
            cbkPasswordFilterExact.Text = Constants.APP_SEARCH_EXACT;
            labelPasswordFilter.Text = UsersStringMapping.Password;
            cbkDisplayNameFilterExact.Text = Constants.APP_SEARCH_EXACT;
            labelDisplayNameFilter.Text = UsersStringMapping.DisplayName;
            cbkUserTypeFilter.Text = Constants.APP_SEARCH;
            cbkEmailFilterExact.Text = Constants.APP_SEARCH_EXACT;
            labelEmailFilter.Text = UsersStringMapping.Email;
            labelPhoneFilter.Text = UsersStringMapping.Phone;
            //end
        }
        //Get entity selected from datagrid
        private UsersEntity GetObject()
        {
            UsersEntity o = controller.MapDataRowToObject(((DataRowView)gridData.SelectedRows[0].DataBoundItem).Row);
            controller.UsersObject = o;
            return o;
        }
        //Get entites selected from datagrid
        private List<DataRow> GetSelectedDataRows()
        {
            List<DataRow> ls = new List<DataRow>();
            for (int i = 0; i < gridData.SelectedRows.Count; i++)
            {
                ls.Add(GetDataRow(gridData.SelectedRows[i].Index));
            }
            return ls;
        }
        //Get the selected data row in datagrid
        private DataRow GetSelectedDataRow()
        {
            DataRow row = GetDataRow(gridData.SelectedRows[0].Index);
            return row;
        }
        //Get the selected data row in datagrid
        private DataRow GetDataRow(int index)
        {
            DataRow row = ((DataRowView)gridData.Rows[index].DataBoundItem).Row;
            return row;
        }
        //Reset all textbox
        private void ClearScreen()
        {
            txtUserName.Text = "";
            txtPassword.Text = "";
            txtDisplayName.Text = "";
            txtEmail.Text = "";
            txtPhone.Text = "";
            errorProviderData.Clear();
        }
        //Lock-Unlock control in screen
        private void LockScreen(bool IsLocked)
        {
            ucCommand.LockControl(IsLocked);
            txtUserName.ReadOnly = IsLocked;
            txtPassword.ReadOnly = IsLocked;
            txtDisplayName.ReadOnly = IsLocked;
            txtEmail.ReadOnly = IsLocked;
            txtPhone.ReadOnly = IsLocked;
            //txtBacSy_ID.ReadOnly = IsLocked;
            txtActived.Enabled = !IsLocked;
            gridRole.ReadOnly = IsLocked;
        }
        //Copy data from control in screen to object
        private void CopyFromSreen(UsersEntity o)
        {
            o.UserName = Convert.ToString(txtUserName.Text);
            if (Flag == ACTIONENUM.AddNew)
            {
                o.Password = Commons.Security.EncriptPassWord(txtPassword.Text);
            }
            else
            {
                if (txtPassword.Text != "******")
                    o.Password = Commons.Security.EncriptPassWord(txtPassword.Text);
            }
            o.DisplayName = Convert.ToString(txtDisplayName.Text);
            if (Flag == ACTIONENUM.AddNew)
                o.UserType = 1;
            o.Email = Convert.ToString(txtEmail.Text);
            o.Phone = Convert.ToString(txtPhone.Text);
            o.Employee_ID = 0; // (int)txtBacSy_ID.SelectedValue;
            o.IsOnline = false;
            o.Actived = txtActived.Checked;
        }
        //Bind data from object to control in screen
        private void CopyToSreen(UsersEntity o)
        {
            if (!o.IsNullUserName)
            {
                txtUserName.Text = Convert.ToString(o.UserName);
            }
            txtPassword.Text = "******";
            if (!o.IsNullDisplayName)
            {
                txtDisplayName.Text = Convert.ToString(o.DisplayName);
            }
            if (!o.IsNullEmail)
            {
                txtEmail.Text = Convert.ToString(o.Email);
            }
            if (!o.IsNullPhone)
            {
                txtPhone.Text = Convert.ToString(o.Phone);
            }
            //if (!o.IsNullEmployee_ID)
            //{
            //    txtBacSy_ID.SelectedValue = o.Employee_ID;
            //}
            if (!o.IsNullActived)
            {
                txtActived.Checked = o.Actived;
            }
        }
        //Validate all data from control in screen before Save data
        protected bool ValidateScreen()
        {
            bool result = true;
            if (txtUserName.Text.Trim() == "")
            {
                errorProviderData.SetError(txtUserName, Constants.MSS_ERROR_TEXT);
                result = false;
            }
            else
            {
                errorProviderData.SetError(txtUserName, "");
            }
            if (!result)
            {
                ShowInfo(Constants.MSS_REQUIRE_FIELD);
            }
            return result;
        }
        //Copy data from selected object to control in screen
        private void BindInfo()
        {
            if (gridData.SelectedRows.Count == 0) return;
            if (gridData.SelectedRows[0].Index < gridData.Rows.Count)
            {
                UsersEntity o = GetObject();
                CopyToSreen(o);
                controller.LoadUserRoles();
                foreach (DataGridViewRow row in gridRole.Rows)
                {
                    DataRow dataRow = ((DataRowView)row.DataBoundItem).Row;
                    dataRow["CHECKED"] = controller.IsUserInRole((int)dataRow["Role_ID"]);
                }
            }
        }
        #endregion
        #region Business
        //AddNew data to database
        private bool AddNewData()
        {
            bool rval = false;
            controller.ResetObject();
            CopyFromSreen(controller.UsersObject);
            rval = controller.AddNew();
            if (rval)
            {
                DataRow row = controller.Table.NewRow();
                row["STT"] = controller.Table.Rows.Count + 1;
                controller.MapObjectToDataRow(row);
                controller.Table.Rows.Add(row);
                gridData.DataSource = null;
                gridData.DataSource = controller.Table;
                AddRoles();
            }
            return rval;
        }
        private void AddRoles()
        {
            List<int> lsChecked = new List<int>();
            foreach (DataGridViewRow row in gridRole.Rows)
            {
                DataRow dataRow = ((DataRowView)row.DataBoundItem).Row;
                if ((bool)dataRow["CHECKED"])
                {
                    lsChecked.Add((int)dataRow["Role_ID"]);
                }
            }
            controller.AddRolesToUser(lsChecked);
        }
        //Update data to database
        private bool UpdateData()
        {
            DataRow row = GetSelectedDataRow();
            controller.LoadObject((Int32)row["User_ID"]);
            CopyFromSreen(controller.UsersObject);
            bool rval = controller.Update();
            if (rval)
            {
                controller.MapObjectToDataRow(row);
                gridData.InvalidateRow(gridData.SelectedRows[0].Index);
                AddRoles();
            }
            return rval;
        }
        //Delete data from database
        private bool DeleteData()
        {
            List<DataRow> ls = GetSelectedDataRows();
            if (ls.Count == 0) return false;
            bool rval = true;
            try
            {
                gridData.DataSource =null;
                foreach (DataRow row in ls)
                {
                    if (row["UserType"].ToString() == "0")
                    {
                        ShowWarning("Bạn không thể xóa người quản trị hệ thống.");
                        continue;
                    }
                    if (controller.DeleteByID((Int32)row["User_ID"]))
                    {
                        this.controller.Table.Rows.Remove(row);
                    }
                    else
                    {
                        rval = false;
                    }
                }
                this.controller.ResetTableIndex();
                gridData.DataSource = this.controller.Table;
            }
            catch
            {
                return false;
            }
            return true;
        }
        #endregion
        #region DataBinding
        //Bind data to datagrid
        private void LoadData()
        {
            gridData.AutoGenerateColumns = false;
           controller.LoadAllDSUsers(true,(byte)txtLoaiFilter.SelectedIndex);
            if (UsersController.User.UserType != 0)
                controller.Table.DefaultView.RowFilter = "UserType>=1";
            gridData.DataSource = controller.Table;
            gridData.AutoResizeColumns();

        }
        #endregion
        #region Windows Control EventHandlers
        private void FrmUsers_Load(object sender, EventArgs e)
        {
            txtLoaiFilter.SelectedIndex = 0;
            LoadLanguage();
            LoadRoles();
            LoadData();
            LockScreen(true);
            this.groupBoxFilter.ToggleCollapsed();
        }
        private void LoadRoles()
        {
            RolesController rolesController = new RolesController();
            DataTable table = rolesController.Table;
            Commons.Common.AddCheckedToTable(table);
            gridRole.AutoGenerateColumns = false;
            gridRole.DataSource = table;
        }
        private void gridData_RowEnter(object sender, DataGridViewCellEventArgs e)
        {
            BindInfo();
        }
        private void ucCommand_OnAddNew(object sender, EventArgs e)
        {
            ClearScreen();
            LockScreen(false);
            Flag = ACTIONENUM.AddNew;
            txtUserName.Focus();
        }
        private void ucCommand_OnDelete(object sender, EventArgs e)
        {
            if (gridData.SelectedRows.Count == 0)
            {
                ShowInfo(Constants.MSS_CHOOSERECORD_REQUIRE);
                return;
            }
            if (!Confirm(Constants.MSS_CONFIRM_DELETE)) return;
            DeleteData();
            this.gridData.Focus();
        }
        private void ucCommand_OnEdit(object sender, EventArgs e)
        {
            if (gridData.SelectedRows.Count == 0)
            {
                ShowInfo(Constants.MSS_CHOOSERECORD_REQUIRE);
                return;
            }
            LockScreen(false);
            Flag = ACTIONENUM.Edit;
            txtUserName.Focus();
        }
        private void ucCommand_OnSave(object sender, EventArgs e)
        {
            if (!ValidateScreen())
                return;
            if (Flag == ACTIONENUM.Edit)
            {
                if (UpdateData())
                {
                    ShowInfo(Constants.MSS_SAVE_SUCCESS);
                }
                else
                {
                    ShowWarning(Constants.MSS_SAVE_FAILE);
                }
                gridData.Focus();
            }
            else
            {
                if (AddNewData())
                {
                    ShowInfo(Constants.MSS_SAVE_SUCCESS);
                }
                else
                {
                    ShowWarning(Constants.MSS_SAVE_FAILE);
                }
            }
            LockScreen(true);
            Flag = ACTIONENUM.None;
        }
        private void ucCommand_OnSkip(object sender, EventArgs e)
        {
            LockScreen(true);
            if (Flag == ACTIONENUM.AddNew)
            {
                ClearScreen();
                ucCommand.SetFocusAddNew();
            }
            else if (Flag == ACTIONENUM.Edit)
            {
                BindInfo();
                this.gridData.Focus();
            }
            Flag = ACTIONENUM.None;
        }
        #endregion
        #region Filters
        private string GetFilter()
        {
            string strFilter = "";
            if (txtUserNameFilter.Text.Trim() != "")
            {
                if (cbkUserNameFilterExact.Checked)
                {
                    strFilter += " AND UserName='" + txtUserNameFilter.Text.Trim() + "'";
                }
                else
                {
                    strFilter += " AND UserName LIKE '%" + txtUserNameFilter.Text.Trim() + "%'";
                }
            }
            if (txtPasswordFilter.Text.Trim() != "")
            {
                if (cbkPasswordFilterExact.Checked)
                {
                    strFilter += " AND Password='" + txtPasswordFilter.Text.Trim() + "'";
                }
                else
                {
                    strFilter += " AND Password LIKE '%" + txtPasswordFilter.Text.Trim() + "%'";
                }
            }
            if (txtDisplayNameFilter.Text.Trim() != "")
            {
                if (cbkDisplayNameFilterExact.Checked)
                {
                    strFilter += " AND DisplayName='" + txtDisplayNameFilter.Text.Trim() + "'";
                }
                else
                {
                    strFilter += " AND DisplayName LIKE '%" + txtDisplayNameFilter.Text.Trim() + "%'";
                }
            }
            if (txtEmailFilter.Text.Trim() != "")
            {
                if (cbkEmailFilterExact.Checked)
                {
                    strFilter += " AND Email='" + txtEmailFilter.Text.Trim() + "'";
                }
                else
                {
                    strFilter += " AND Email LIKE '%" + txtEmailFilter.Text.Trim() + "%'";
                }
            }
            
            if (strFilter.Length > 0)
                strFilter = strFilter.Substring(4);
            return strFilter;
        }
        private void FilterData()
        {
            gridData.ClearSelection();
            controller.Table.DefaultView.RowFilter = GetFilter();
        }
        private void btnSearch_Click(object sender, EventArgs e)
        {
            FilterData();
        }
        #endregion
    }
}
